// 购物车相关信息的存储仓库

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useUserStore } from './user'
import { insertCarAPI, findNewCarListAPI, delCarAPI } from '@/apis/car'

// 创建仓库
export const useCarStore = defineStore('car', ()=>{
    const userStore = useUserStore()
    const isLogin = computed(()=>{
        return userStore.userInfo.token
    })
    // 定义state -> 购物车列表
    const carList = ref([])

    // 定义action -> 添加物品到购物车列表的方法
    const addCar = async (goods) =>{
        const { skuId, count } = goods
        // 根据isLogin判断用户是否登录
        if(isLogin.value){
            await insertCarAPI({ skuId, count })
            updateNewList()
        }else{
            // 如果在carList中能够找到传递接收的参数goods下的skuId，就说明这个商品已经被添加到购物车了
            const item = carList.value.find((item)=>{
                return goods.skuId === item.skuId
            })
            if(item){
                // 如果当前商品已经被添加到购物车了，那么就 count + 1
                item.count++
            }else{
                // 如果没有添加过，那么就将这个商品 push 到 carList中
                carList.value.push(goods)
            }
        }
    }
    // 定义action -> 将物品从购物车列表中删除的方法
    const delCar = async (skuId) => {
        if(isLogin.value){
            await delCarAPI([skuId])
            updateNewList()
        }else {
            // console.log(skuId);
            // 利用findIndex方法获取要被删除的商品的下标值
            const index = carList.value.findIndex((item)=>{
                return skuId === item.skuId
            })
            // 利用下标值和splice方法将对应的商品删除
            carList.value.splice(index,1)
        }
    }
    // 定义action -> 单个商品选中状态改变的方法
    const singleCheck = (skuId,selected) => {   // selected是该指定商品要被修改成的状态值
        // 利用find方法获取要被修改选中状态的商品
        const item = carList.value.find((item)=>{
            return skuId === item.skuId
        })
        item.selected = selected
    }
    // 定义action -> 所有商品选中状态改变的方法
    const allCheck = (selected)=>{
        // 将商品列表下的所有商品的选中状态修改成传递过来的selected属性值
        carList.value.forEach((item) => {
            item.selected = selected
        });
    }
    // 定义action -> 更新购物车中的商品列表数据的方法
    const updateNewList = async ()=>{
        const res = await findNewCarListAPI()
        carList.value = res.result
    }
    // 定义action -> 清除购物车中的所有商品数据的的方法
    const clearCar = async ()=>{
        carList.value = []
    }

    // 定义计算属性
    // 1. 商品总数
    const allCount = computed(()=>{
        return carList.value.reduce((prev,curr)=>{  // curr 是当前遍历的元素
            return prev+curr.count      // 这里返回的值会成为下一次遍历时的prev值
        },0)    // 这里的 0 是最初的初始值，也就是最初的prev属性值
    })
    // 2. 商品总价
    const allPrice = computed(()=>{
        return carList.value.reduce((prev,curr)=>{  // curr 是当前遍历的元素
            return prev+curr.count * curr.price      // 这里返回的值会成为下一次遍历时的prev值
        },0)    // 这里的 0 是最初的初始值，也就是最初的prev属性值
    })
    // 3. 是否所有商品的状态都是选中
    const isAll = computed(()=>{
        return carList.value.every((item)=>{    // every方法对carList进行遍历，如果每次遍历返回的结果都是true，那么这次every方法的调用结果就是true
            return item.selected === true;
        })
    })
    // 4. 选中状态的商品的总价
    const selectedPrice = computed(()=>{
        return carList.value.filter((item) => {
            // 利用filter方法过滤carList数组，只有当元素的selected值为true时，当前这个元素才会被保留到过滤后的数组中
            return item.selected === true
        }).reduce((prev,curr)=>{    // 用reduce方法对过滤后的数组进行处理
            return prev + curr.count * curr.price
        },0)
    })
    // 5. 选中状态的商品的数量
    const selectedCount = computed(()=>{
        return carList.value.filter((item) => {
            // 利用filter方法过滤carList数组，只有当元素的selected值为true时，当前这个元素才会被保留到过滤后的数组中
            return item.selected === true
        }).reduce((prev,curr)=>{    // 用reduce方法对过滤后的数组进行处理
            return prev + curr.count
        },0)
    })

    // 将 state 和 action 以及 计算属性 返回出去
    return {
        carList,
        addCar,
        delCar,
        clearCar,
        singleCheck,
        allCheck,
        updateNewList,
        allCount,
        allPrice,
        isAll,
        selectedPrice,
        selectedCount
    }
},{
    // 这里是配置持久化仓库，配置完后，会自动将当前这个仓库中的state数据carList购物车列表数据存进localhost本地存储，运用到了 pinia-plugin-persistedstate 库
    persist: true
})